<?php

/**
 * This is the model class for table "{{category}}".
 *
 * The followings are the available columns in table '{{category}}':
 * @property integer $id
 * @property integer $parent_id
 * @property integer $account_id
 * @property string $module
 * @property integer $module_id
 * @property integer $position
 * @property integer $availability_code
 * @property integer $status_code
 * @property string $create_timezone
 * @property string $create_timestamp
 * @property string $create_datetime
 * @property string $create_date
 * @property string $create_time
 * @property integer $create_by
 * @property string $update_timezone
 * @property string $update_timestamp
 * @property string $update_datetime
 * @property string $update_date
 * @property string $update_time
 * @property integer $update_by
 */
class Category extends AccountRecord {

    public $title_;
    
    public $parent_;
    public $accountId_;
    public $module_;
    public $moduleId_;
    public $logo_;
    
    public $availability_;
    public $language_;
    public $publish_;
    public $position_;
    public $status_;
    
    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return ListingCategory the static model class
     */
    public static function model($className = __CLASS__) {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName() {
        return '{{category}}';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules() {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('id_, title_, parent_, logo_, availability_, publish_, position_, status_', 'safe', 'on' => 'userCreate, userUpdate, adminSearch, adminCreate, adminUpdate'),
            
            array('logo_, image_', 'file', 'types' => 'jpg,gif,png', 'allowEmpty' => true, 'maxSize' => Yii::app()->params['maxAvatarSize'], 'on' => 'adminCreate, adminUpdate, userCreate, userUpdate'),
            
            // must included
            array('var_', 'ext.validators.BotDetectionValidator'),
            array('var_', 'safe'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations() {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
            // must included
            'creator' => array(self::BELONGS_TO, 'User', 'create_by'),
            'editor' => array(self::BELONGS_TO, 'User', 'update_by'),
            
            // customed
            'account'=> array(self::BELONGS_TO, 'Account', 'account_id', 'scopes'=>array('accessible')),
            'html' => array(self::HAS_ONE, 'Content', 'module_id', 'scopes' => array('module' => __CLASS__, 'language'=>$this->defaultLanguage)),
            'defaultHtml' => array(self::HAS_ONE, 'Content', 'module_id', 'scopes' => array('module' => __CLASS__, 'language' => $this->defaultLanguage)),
            
            'photo' => array(self::HAS_ONE, 'Gallery', 'module_id', 'scopes' => array('module' => __CLASS__, 'primary', 'accessible')),
            'item'=>array(self::HAS_MANY, 'Item', 'category_id'),
            'shortlist'=>array(self::HAS_MANY, 'ShortList', array('id'=>'module_id'), 'through'=>'item'),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels() {
        return array(
            'parent_' => Lang::t('item.category.lbl.parent'),
            'image_' => Lang::t('item.category.lbl.image'),
            'title_' => Lang::t('item.category.lbl.title'),
            'description_' => Lang::t('item.category.lbl.description'),
            'sefUrl_' => Lang::t('item.category.lbl.sef.url'),
            'metaTitle_' => Lang::t('item.category.lbl.meta.title'),
            'metaDescription_' => Lang::t('item.category.lbl.meta.description'),
            'metaKeywords_' => Lang::t('item.category.lbl.meta.keywords'),
            'availability_' => Lang::t('item.category.lbl.availability'),
            'publish_' => Lang::t('item.category.lbl.publish'),
            'postion_' => Lang::t('item.category.lbl.position'),
        );
    }

    public function scopes() {
        $t = $this->getTableAlias(false);
        return array(
            'published' => array(
                'condition' => $t.'.status_code=:activeStatus'.$t,
                'params' => array(
                    ':activeStatus'.$t => Option::STATUS_ACTIVE,
                ),
            ),
            'ordered'=>array(
                'order'=>$t.'.position ASC',
            ),
            'accessible'=>array(
                'condition' => $t.'.status_code <> :deletedStatus'.$t,
                'params' => array(
                    ':deletedStatus'.$t => Option::STATUS_DELETED,
                ),
            ),
        );
    }

    public function module($module = null) {
        $t = $this->getTableAlias(false);
        $this->getDbCriteria()->mergeWith(array(
            'condition' => $t . '.module=:module',
            'params' => array(
                ':module' => strtolower($module),
            ),
        ));
        return $this;
    }

    public function moduleId($id = null) {
        $t = $this->getTableAlias(false);
        $this->getDbCriteria()->mergeWith(array(
            'condition' => $t . '.module_id=:moduleId'.$t,
            'params' => array(
                ':moduleId'.$t => (int)$id,
            ),
        ));
        return $this;
    }    
    
    public function autoFill() {
        switch ($this->scenario) {
            case 'adminCreate':
            case 'userCreate':
                $this->publish_ = true;
                break;
            
            case 'adminUpdate':
                $this->parent_=$this->parent_id;
                $this->module_=$this->module;
                $this->availability_ = (int) $this->availability_code;
                $this->publish_ = $this->status_code == Option::STATUS_ACTIVE ? true : false;
                $this->position_ = $this->position;
                $this->image_=!empty($this->photo);
                break;
        }//end switch
    }
    
    protected function beforeSave() {
        if (parent::beforeSave()) {
            
            if (in_array($this->scenario, array('adminUpdate'))) {
                if(empty($this->parent_)) $this->parent_=0;
                if ($this->parent_id != $this->parent_) {
                    $this->oldParent_ = $this->parent_id;
                    $this->oldPosition_ = $this->position;
                    $this->position = 0;
                }
            }

            switch($this->scenario){
                case 'adminDelete':
                case 'userDelete':
                    break;
                default:
                    $this->parent_id = empty($this->parent_) ? 0 : $this->parent_;
                    $this->availability_code = $this->availability_;
                    $this->status_code = empty($this->publish_) ? Option::STATUS_INACTIVE : Option::STATUS_ACTIVE;
                    break;
            }//end switch
            
            $this->account_id=$this->accountId_;
            
            if ($this->isNewRecord) {
                $this->position = 0;
                $this->module=strtolower($this->module_);
                $this->module_id=$this->moduleId_;
                $this->setCreateDateTime();
            } else {
                $this->setUpdateDateTime();
            }
            return true;
        }
        else
            return false;
    }

    protected function afterSave() {
        parent::afterSave();
        $this->updatePosition('module = "'.$this->module.'"');
    }
    
    public function generateJson($type='item'){
        $this->language_=$this->defaultLanguage;
        $jsonName=implode('_', array_filter(array(
            $type,
            __CLASS__,
            $this->language_
        )));
        $data=$this->readJsonFile($jsonName);
        
        if($this->status_code==Option::STATUS_ACTIVE){
            $data[$this->id]=array(
                'parent'=>$this->parent_id,
                'logo'=>empty($this->photo)?null: $this->thumbnail,
                'title'=>$this->title,
                'description'=>$this->description,
            );
        }elseif(isset($data[$this->id]))
            unset($data[$this->id]);
        
        $this->createJsonFile($data, $jsonName);
    }
    
    public function regenerateJson($type='item'){
        $models=$this->module($type)->findAll();
        foreach($models as $data){
            $data->generateJson($type);
        }
        return true;
    }
    
    public function generateJson2(){
        $categoryId = array_keys(CHtml::listData($this->published()->findAll(), 'id', 'id'));
        $model=Content::model()->module(__CLASS__)->moduleIdRange($categoryId)->findAll();
        $contents=array();
        foreach ($model as $data) {
            $contents[$data->languageCode][$data->moduleId]=array(
                'parent'=>empty($this->parent_id)? 0:$this->parent_id,
                'logo'=>empty($this->photo)? null: $this->thumbnail,
                'title'=>$data->title,
                'description'=>$data->description,
            );
        }
        
        foreach($contents as $language=>$content){
            $this->createJsonFile($content, implode('_', array_filter(array(
                $this->module_,
                __CLASS__,
                $language,
            ))));
        }
    }    
    
    public function getStatusOption($id=null){
        $option = array_intersect_key(Option::recordStatus(), array(
            Option::STATUS_ACTIVE => '',
            Option::STATUS_ARCHIVED=>'',
            Option::STATUS_SUSPENDED=>'',
        ));
        if($id===null) return $option; return isset($option[$id])? $option[$id]:null;
    }
    
    public function getParentOption($parent=0, $lvl=0) {
        $options = array();
        $criteria = new CDbCriteria;
        $criteria->compare('parent_id', $parent);
        $criteria->order='position ASC';
        if (!$this->isNewRecord) {
            $criteria->addCondition('id <> '.$this->id);
        }
        $models = $this->accessible()->findAll($criteria);
        $prefix=str_repeat('> ',$lvl++);
        foreach ($models as $data) {
            $options[$data->id] = $prefix.$data->title;
            $options+=$this->getParentOption($data->id,$lvl);
        }
        return $options;
    }

    public function getAvailabilityOption($id = null) {
        return Option::availability($id);
    }

    
    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search() {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.
        $t=$this->getTableAlias(false);
        $criteria = new CDbCriteria;
        
        $criteria->compare($t.'.module',$this->module_);
        $criteria->compare($t.'.id', $this->id_);
        if(empty($this->parent_)) $this->parent_=0;
        $criteria->compare($t.'.parent_id',$this->parent_);
        $criteria->compare($t.'.status_code', $this->status_);
        
        $criteria->order = $t.'.position ASC';
        /*
        $criteria->addCondition(array(
            $t.'.status_code <> '.Option::STATUS_DELETED,
        ));*/
        switch($this->scenario){
            case 'adminSearch':
                $model=$this->accessible();
                break;
            case 'search':
            default:
                $model=$this->published();
                break;
        }//end class
        
        return new ActiveDataProvider($model, array(
            'criteria' => $criteria,
        ));
    }
    
    public function findAllShortlisted(){
        $t=$this->getTableAlias(false);
        $criteria = new CDbCriteria;
        $criteria->order = $t.'.position ASC';
        $criteria->with = array(
            'item' => array(
                'joinType' => 'INNER JOIN',
                'scopes' => array('published'),
            ),
            'shortlist' => array(
                'joinType' => 'INNER JOIN',
                'scopes' => array('accessible', 'userId' => $this->userId_),
            ),
        );
        $criteria->together = true;
        
        return new ActiveDataProvider($this->published(), array(
            'criteria' => $criteria,
        ));
    }
    
    public function findAllInHierarchy(){
        $data=$this->readJsonFile(implode('_',array(
            $type,
            __CLASS__,
            $this->defaultLanguage,
            )));
        if($data){
            function hierarchy(&$data, $parent=0){
                $option=array();
                foreach($data as $id=>$content){
                    $option[$id]=$content['title'];
                }
            }
            return hierarchy($data);
        }
        return array();
    }
    
    
    public function findAllInArray($type='item'){
        
        $data=$this->readJsonFile(implode('_',array(
            $type,
            __CLASS__,
            $this->defaultLanguage,
            )));
        
        $category=array();
        if(!empty($data)){
            foreach($data as $id=>$content){
                $category[$id]=$content['title'];
            }
            return $category;
        }
        $model = $this->with(array(
            'html'=>array(
                'joinType'=>'INNER JOIN',
            )
        ))->published()->findAll();
        return CHtml::listData($model, 'id', function($model){
            return $model->title;
        });
    }    
    
    public function getAll($parentId = 0) {
        $model = $this->findAll('parent_id = :parentId', array(':parentId' => $parentId));
    }

    public function gridTitle($data, $row){
        echo $data->title;
        $this->getChildren($data->id);
    }
    
    public function getUrl() {
        switch($this->scenario){
            case 'update':
                return Yii::app()->controller->createUrl('item', array(
                    'id'=>$this->id,
                    'title'=>$this->sefUrl,
                ));
                break;
            default:
                return Yii::app()->createUrl('product/searchresult', array(
                    'id' => $this->id,
                    'title'=>$this->sefUrl,
                ));
                break;
        }//end switch
    }
    
    public function getIsPublish() {
        return !empty($this->status_code) && $this->status_code == Option::STATUS_ACTIVE;
    }

    public function getPosition() {
        return (int) $this->position;
    }
    
    public function getThumbnail($value=null) {
        switch($this->scenario){
            case 'update':
            case 'adminUpdate':
                return parent::getThumbnail();
                break;
            default:
                if($this->item){
                    $image = $this->item[0]->thumbnail;
                    return empty($image)? $this->defaultImage:$image;
                }else    
                    return parent::getThumbnail();
                break;
        }//end switch
    }
    
}//end class